﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace daSyntaxAnalyser.SyntaxTree
{
    using daBase.Objects;

    public class UnitElement : FileElement
    {
        private TypeDeclarationsElement types;
        private List<ISyntaxTreeElement> interfaces;
        private List<ISyntaxTreeElement> implementations;
        private List<StatementsElement> initialization;
        private List<StatementsElement> finalization;

        public TypeDeclarationsElement Types { get { return types; } set { types = value; } }
        public List<ISyntaxTreeElement> Interfaces { get { return interfaces; } set { interfaces = value; } }
        public List<ISyntaxTreeElement> Implementations { get { return implementations; } set { implementations = value; } }
        public List<StatementsElement> Initialization { get { return initialization; } set { initialization = value; } }
        public List<StatementsElement> Finalization { get { return finalization; } set { finalization = value; } }

        public UnitElement(TokenInfo StartInfo, string Path, IdElement Name, UsesElement Uses, TypeDeclarationsElement Types, List<ISyntaxTreeElement> Interfaces, List<ISyntaxTreeElement> Implementations, List<StatementsElement> Initialization, List<StatementsElement> Finalization, List<TokenInfo> Comments)
            : base(StartInfo, Path, Name, Uses, Comments)
        {
            types = Types;
            interfaces = Interfaces;
            implementations = Implementations;
            initialization = Initialization;
            finalization = Finalization;
        }

        public override string ToString()
        {
            string result;
            result = string.Format("unit {0};\r\n\r\n", name);
            if (types != null)
                result += string.Format("{0}\r\n\r\n", types);
            result += "interface\r\n\r\n";
            if (uses != null)
                result += string.Format("{0}\r\n\r\n", uses);
            if (interfaces != null)
                result += string.Format("{0}\r\n\r\n", interfaces.Join("\r\n\r\n"));
            if (implementations != null)
                result += string.Format("implementation\r\n\r\n{0}\r\n\r\n", Tabulate(implementations.Join("\r\n\r\n")));
            if (initialization != null)
                result += string.Format("initialization\r\n\r\n{0}\r\n\r\n", Tabulate(initialization.Join("\r\n\r\n")));
            if (finalization != null)
                result += string.Format("finalization\r\n\r\n{0}\r\n\r\n", Tabulate(finalization.Join("\r\n\r\n")));
            return string.Format("{0}end.", result);
        }

        protected override IEnumerator<ISyntaxTreeElement> CreateEnumerator()
        {
            IEnumerator<ISyntaxTreeElement> baseEnumerator = base.CreateEnumerator();
            while (baseEnumerator.MoveNext())
                yield return baseEnumerator.Current;
            if (types != null)
                yield return types;
            if (interfaces != null)
                foreach (ISyntaxTreeElement _interface in interfaces)
                    yield return _interface;
            if (implementations != null)
                foreach (ISyntaxTreeElement implementation in implementations)
                    yield return implementation;
            if (initialization != null)
                foreach (StatementsElement init in initialization)
                    yield return init;
            if (finalization != null)
                foreach (StatementsElement final in finalization)
                    yield return final;
        }

        protected override void SaveMe(string AsFile)
        {
            base.SaveMe(AsFile);
            foreach (ISyntaxTreeElement implementation in implementations)
                if (implementation is UsesElement)
                    RecursiveSaveTo(implementation as UsesElement, new FileInfo(AsFile).DirectoryName);
        }

        protected override void ResetMe()
        {
            base.ResetMe();
            foreach (ISyntaxTreeElement implementation in implementations)
                if (implementation is UsesElement)
                    RecursiveReset(implementation as UsesElement);
        }
    }
}
